#include<iostream>
#include<unistd.h>
#include<signal.h>

using namespace std;


// 如果我们不想等待子进程，并且我们还想让子进程退出后，自动释放僵尸子进程
int main()
{
    signal(SIGCHLD, SIG_IGN); // 手动式对子进程的信号进行忽略。
    if (fork() == 0)
    {
        cout << "child: " << getpid() << endl;
        sleep(5);
        exit(1);
    }
    
    while (true)
    {
        cout << "parent: " << getpid() << "执行我自己的任务! " << endl;
        sleep(1);
    }

    return 0;
}






// // 子进程退出，会给父进程发送17号信号
// void handler(int signum)
// {
//     cout << "子进程退出: " << signum << getpid() << endl;
// }

// int main()
// {
//     signal(SIGCHLD, handler);
//     if (fork() == 0)
//     {
//         cout << "pid(): " << getpid() << endl;
//         sleep(1);
//         exit(0);
//     }

//     while(true) sleep(1);

//     return 0;
// }







// // 全局变量的优化
// // int flag = 0;
// volatile int flag = 0;

// void changeFlag(int signum)
// {
//     (void) signum;
//     cout << "change flag: " << flag;
//     flag = 1;
//     cout << "->" << flag << endl;
// }

// int main()
// {
//     signal(2, changeFlag);
//     while (!flag);
//     cout << "进程正常退出后: " << flag << endl;
//     return 0;
// }






// // OS处理信号时，如果有其他外来信号，会把外来信号直接屏蔽掉 (放在block中)。
// void showPending(sigset_t pending)
// {
//     for (int sig = 1; sig <= 31; sig++)
//     {
//         if (sigismember(&pending, sig)) cout << "1";
//         else cout << "0";
//     }
//     cout << endl;
// }

// void handler(int signum)
// {
//     cout << "获取了一个信号: " << signum << endl;
    
//     sigset_t pending;
//     int c = 20;
//     while (true)
//     {
//         sigpending(&pending);
//         showPending(pending);
//         c--;
//         if(!c) break;
//         sleep(1);
//     }

// }

// int main()
// {
//     // signal(2, SIG_IGN);
    
//     cout << getpid() << endl;

//     // 内核数据类型, 用户栈定义的
//     struct sigaction act, oact;
//     act.sa_flags = 0;
//     sigemptyset(&act.sa_mask);
//     act.sa_handler = handler;

//     sigaddset(&act.sa_mask, 3);
//     sigaddset(&act.sa_mask, 4);
//     sigaddset(&act.sa_mask, 5);
//     sigaddset(&act.sa_mask, 6);
//     sigaddset(&act.sa_mask, 7);

//     // 设置进当前进程的PCB
//     sigaction(2, &act, &oact);

//     cout << "default action: " << (int) oact.sa_handler << endl;
    
//     while(true) sleep(1);
//     return 0;
// }